using System.Security.Claims;
using UniversalAdminSystem.Application.Authentication.Interfaces;
using UniversalAdminSystem.Domian.UserManagement.ValueObj;

namespace UniversalAdminSystem.Api.Middleware;

public class JwtAuthenticationMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IJwtTokenService _jwtService;
    private readonly ILogger<JwtAuthenticationMiddleware> _logger;

    public JwtAuthenticationMiddleware(
        RequestDelegate next,
        IJwtTokenService jwtService,
        ILogger<JwtAuthenticationMiddleware> logger)
    {
        _next = next;
        _jwtService = jwtService;
        _logger = logger;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        try
        {
            var token = ExtractTokenFromHeader(context);
            Console.WriteLine($"提取到的Token: {(token != null ? "存在" : "不存在")}");
            if (!string.IsNullOrEmpty(token))
            {
                Console.WriteLine($"Token内容: {token.Substring(0, Math.Min(50, token.Length))}...");
                var userInfo = await AuthenticateTokenAsync(token);
                if (userInfo.HasValue)
                {
                    Console.WriteLine($"Token解析结果 - 用户ID: {userInfo.Value.UserId}, 角色ID: {userInfo.Value.RoleId}, 状态: {userInfo.Value.status}");
                    SetUserClaims(context, userInfo.Value);
                    _logger.LogInformation("用户 {UserId} 认证成功", userInfo.Value.UserId);
                }
                else
                {
                    Console.WriteLine("Token解析失败");
                }
            }
            else
            {
                Console.WriteLine("Token不存在");
            }
        }
        catch (Exception ex)
        {
            _logger.LogWarning("JWT认证中间件异常: {Message}", ex.Message);
        }

        await _next(context);
    }

    private string? ExtractTokenFromHeader(HttpContext context)
    {
        var authHeader = context.Request.Headers["Authorization"].FirstOrDefault();
        Console.WriteLine($"Authorization头: {authHeader ?? "null"}");

        if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
        {
            Console.WriteLine("Authorization头为空或不以Bearer开头");
            return null;
        }
        
        var token = authHeader.Substring("Bearer ".Length).Trim();
        Console.WriteLine($"提取的Token长度: {token.Length}");
        Console.WriteLine($"Token前50个字符: {token.Substring(0, Math.Min(50, token.Length))}");
        
        // 检查token格式
        if (string.IsNullOrEmpty(token))
        {
            Console.WriteLine("Token为空");
            return null;
        }
        
        // JWT应该包含两个点，格式为: header.payload.signature
        var parts = token.Split('.');
        if (parts.Length != 3)
        {
            Console.WriteLine($"Token格式错误，包含{parts.Length}个部分，应该是3个部分");
            return null;
        }
        
        Console.WriteLine("Token格式检查通过");
        return token;
    }

    private async Task<(string UserId, string RoleId, UserStatus status)?> AuthenticateTokenAsync(string token)
    {
        try
        {
            var (userId, roleId, status) = _jwtService.ParseToken(token);
            Console.WriteLine($"Token解析结果 - 用户ID: {userId}, 角色ID: {roleId}, 状态: {status}");
            return (userId, roleId, status);
        }
        catch (Exception ex)
        {
            _logger.LogWarning("Token解析失败: {Message}", ex.Message);
            return null;
        }
    }

    private void SetUserClaims(HttpContext context, (string UserId, string RoleId, UserStatus status) userInfo)
    {
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.NameIdentifier, userInfo.UserId),
            new Claim(ClaimTypes.Role, userInfo.RoleId),
            new Claim(ClaimTypes.StateOrProvince, userInfo.status.ToString()),
        };

        var identity = new ClaimsIdentity(claims, "jwt");
        context.User = new ClaimsPrincipal(identity);
    }
}

public static class JwtAuthenticationMiddlewareExtensions
{
    public static IApplicationBuilder UseJwtAuthentication(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<JwtAuthenticationMiddleware>();
    }
}